package com.pine.dcts.service;

import com.pine.dcts.taskScheduling.scheduler.DynamicScheduler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.Future;
import java.util.concurrent.ThreadPoolExecutor;

/**
 * @author xiaoyuan
 * @create 2021/1/13 20:05
 **/
@Slf4j
public class DefaultTaskRunnerPool implements TaskRunnerPool {

    ThreadPoolTaskExecutor executor;

    private Map<Integer, Task> jobPool = new HashMap<>();



    public DefaultTaskRunnerPool() {
        executor = new ThreadPoolTaskExecutor();
        //1: 核心线程数目
        executor.setCorePoolSize(2);
        //2: 指定最大线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(10);
        //3: 队列中最大的数目
        executor.setQueueCapacity(200);
        //4: 线程名称前缀
        executor.setThreadNamePrefix("job-");
        //5:当pool已经达到max size的时候，如何处理新任务
        // CallerRunsPolicy: 会在execute 方法的调用线程中运行被拒绝的任务,如果执行程序已关闭，则会丢弃该任务
        // AbortPolicy: 抛出java.util.concurrent.RejectedExecutionException异常
        // DiscardOldestPolicy: 抛弃旧的任务
        // DiscardPolicy: 抛弃当前的任务
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //6: 线程空闲后的最大存活时间(默认值 60),当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(60);
        //7:线程空闲时间,当线程空闲时间达到keepAliveSeconds(秒)时,线程会退出,直到线程数量等于corePoolSize,如果allowCoreThreadTimeout=true,则会直到线程数量等于0
        executor.setAllowCoreThreadTimeOut(false);
        executor.initialize();
    }

    @Override
    public void submit(Task task, TaskRunnerCallback callback) {
        TaskRunnerDelegate taskRunnerDelegate = new TaskRunnerDelegate(task, callback);
        taskRunnerDelegate.cllback(t -> {
            jobPool.remove(t.getTaskMeta().getTaskId());
        });
        Future future = executor.submit(new TaskRunnerDelegate(task, callback));
        jobPool.put(task.getTaskMeta().getTaskId(), task);
        if (log.isDebugEnabled()) {
            log.debug("任务已提交成功！信息：{}", task.toString());
        }
    }

    @Override
    public void shutdowm() {
        executor.shutdown();
    }
}
